package com.zhida.common.interceptor;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhida.common.context.UserContext;
import com.zhida.common.utils.ObjectUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.zhida.common.utils.StaticKeyUtil.TOKEN_KEY;
import static com.zhida.common.utils.StaticKeyUtil.USER_ROLE_KEY;

/**
 * Create by zhh 2024/7/5 1:14
 */
@Slf4j
@Component
public class UserInfoInterceptor implements HandlerInterceptor {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();

        // 处理错误请求
        if ("/error".equals(requestURI)) {
            sendErrorResponse(response, 500, "请求错误，请稍后重试");
            return false;
        }

        // 获取用户角色和权限
        String roleJson = redisTemplate.opsForValue().get(USER_ROLE_KEY);
        List<Map<String, String>> permissions = parsePermissions(roleJson);

        String userInfo = redisTemplate.opsForValue().get(TOKEN_KEY + UserContext.getUser());
        JsonNode userNode = ObjectUtil.JsonStr2Object(userInfo);

        // 检查用户权限级别
        Integer userLevel = getUserLevel(userNode);
        if (userLevel == null) {
            sendErrorResponse(response, 403, "请重新登陆！");
            return false;
        }

        // 权限检查
        boolean hasPermission = permissions.stream()
                .anyMatch(permission -> requestURI.contains(permission.get("URI")) &&
                        Integer.parseInt(permission.get("permission_level")) >= userLevel);

        if (!hasPermission) {
            sendErrorResponse(response, 403, "权限不足");
            return false;
        }

        return true;
    }

    // 辅助方法：发送错误响应
    private void sendErrorResponse(HttpServletResponse response, int code, String message) throws IOException {
        Map<String, String> json = new HashMap<>();
        json.put("code", String.valueOf(code));
        json.put("msg", message);
        response.setContentType("application/json");
        response.getWriter().append(ObjectUtil.Object2JsonStr(json));
    }

    // 辅助方法：解析权限列表
    private List<Map<String, String>> parsePermissions(String roleJson) {
        if (roleJson == null) {
            return Collections.emptyList();
        }
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(roleJson, new TypeReference<List<Map<String, String>>>() {});
        } catch (JsonProcessingException e) {
            log.error("Error parsing permissions from Redis", e);
            return Collections.emptyList();
        }
    }

    // 辅助方法：获取用户级别
    private Integer getUserLevel(JsonNode userNode) {
        JsonNode roleLevelNode = userNode.get("role_level");
        if (roleLevelNode == null || !roleLevelNode.isInt()) {
            return null;
        }
        return roleLevelNode.asInt();
    }
}
